#include "idt.h"
#include "screen.h"
#include "io.h"

/**
 * Properties refer to P DPL 0 D 1 1 0
 * D = 1 (1 -> 32 bits ; 0 -> 16 bits)
 * P = 1 (1 -> present; 0 -> not present)
 * DPL  = 0 
 */

struct s_idt idt;
struct s_idt_table idt_table[256];

void init_idt()
{
	int i;

	for(i = 0; i < 256; i++)
	{
		idt_table[i].offset_low = 0x0;
		idt_table[i].segment_selector = 0x0;
		idt_table[i].zero = 0x0;
		idt_table[i].properties = 0x0;
		idt_table[i].offset_high = 0x0;
	}

	idt.entries = ((256*8)-1);
	idt.base_address = (unsigned int)&idt_table[0];
}

void add_idt_entry(unsigned int index, unsigned int address, 
               unsigned short segment, unsigned char properties)
{
	unsigned short low;
	unsigned short high;
	
	low  = (unsigned short)(0x0000FFFF & address);
	high = (unsigned short)((0xFFFF0000 & address) >> 16);
	
	idt_table[index].offset_low = low;
	idt_table[index].segment_selector = segment;
	idt_table[index].zero = 0x0;
	idt_table[index].properties = properties;
	idt_table[index].offset_high = high;
}

void setup_idt()
{
	int i;
	
	irq_remap();
	
	add_idt_entry(0,  (unsigned int)__int0,  0x08, 0x8E);
	add_idt_entry(1,  (unsigned int)__int1,  0x08, 0x8E);
	add_idt_entry(2,  (unsigned int)__int2,  0x08, 0x8E);
	add_idt_entry(3,  (unsigned int)__int3,  0x08, 0x8E);
	add_idt_entry(4,  (unsigned int)__int4,  0x08, 0x8E);
	add_idt_entry(5,  (unsigned int)__int5,  0x08, 0x8E);
	add_idt_entry(6,  (unsigned int)__int6,  0x08, 0x8E);
	add_idt_entry(7,  (unsigned int)__int7,  0x08, 0x8E);
	add_idt_entry(8,  (unsigned int)__int8,  0x08, 0x8E);
	add_idt_entry(9,  (unsigned int)__int9,  0x08, 0x8E);
	add_idt_entry(10,  (unsigned int)__int10,  0x08, 0x8E);
	add_idt_entry(11,  (unsigned int)__int11,  0x08, 0x8E);
	add_idt_entry(12,  (unsigned int)__int12,  0x08, 0x8E);
	add_idt_entry(13,  (unsigned int)__int13,  0x08, 0x8E);
	add_idt_entry(14,  (unsigned int)__int14,  0x08, 0x8E);
	add_idt_entry(15,  (unsigned int)__int15,  0x08, 0x8E);
	add_idt_entry(16,  (unsigned int)__int16,  0x08, 0x8E);
	add_idt_entry(17,  (unsigned int)__int17,  0x08, 0x8E);
	add_idt_entry(18,  (unsigned int)__int18,  0x08, 0x8E);
	add_idt_entry(19,  (unsigned int)__int19,  0x08, 0x8E);
	add_idt_entry(20,  (unsigned int)__int20,  0x08, 0x8E);
	add_idt_entry(21,  (unsigned int)__int21,  0x08, 0x8E);
	add_idt_entry(22,  (unsigned int)__int22,  0x08, 0x8E);
	add_idt_entry(23,  (unsigned int)__int23,  0x08, 0x8E);
	add_idt_entry(24,  (unsigned int)__int24,  0x08, 0x8E);
	add_idt_entry(25,  (unsigned int)__int25,  0x08, 0x8E);
	add_idt_entry(26,  (unsigned int)__int26,  0x08, 0x8E);
	add_idt_entry(27,  (unsigned int)__int27,  0x08, 0x8E);
	add_idt_entry(28,  (unsigned int)__int28,  0x08, 0x8E);
	add_idt_entry(29,  (unsigned int)__int29,  0x08, 0x8E);
	add_idt_entry(30,  (unsigned int)__int30,  0x08, 0x8E);
	add_idt_entry(31,  (unsigned int)__int31,  0x08, 0x8E);
	add_idt_entry(32,  (unsigned int)__int32,  0x08, 0x8E);
	add_idt_entry(33,  (unsigned int)__int33,  0x08, 0x8E);
	add_idt_entry(34,  (unsigned int)__int34,  0x08, 0x8E);
	add_idt_entry(35,  (unsigned int)__int35,  0x08, 0x8E);
	add_idt_entry(36,  (unsigned int)__int36,  0x08, 0x8E);
	add_idt_entry(37,  (unsigned int)__int37,  0x08, 0x8E);
	add_idt_entry(38,  (unsigned int)__int38,  0x08, 0x8E);
	add_idt_entry(39,  (unsigned int)__int39,  0x08, 0x8E);
	add_idt_entry(40,  (unsigned int)__int40,  0x08, 0x8E);
	add_idt_entry(41,  (unsigned int)__int41,  0x08, 0x8E);
	add_idt_entry(42,  (unsigned int)__int42,  0x08, 0x8E);
	add_idt_entry(43,  (unsigned int)__int43,  0x08, 0x8E);
	add_idt_entry(44,  (unsigned int)__int44,  0x08, 0x8E);
	add_idt_entry(45,  (unsigned int)__int45,  0x08, 0x8E);
	add_idt_entry(46,  (unsigned int)__int46,  0x08, 0x8E);
	add_idt_entry(47,  (unsigned int)__int47,  0x08, 0x8E);
	add_idt_entry(48,  (unsigned int)__int48,  0x08, 0x8E);
}

/**
 * Function stolen from Bran's Kernel development tutorial
 * I was kinda lazy to read about the details on 8259
 * Reference to the code: http://www.osdever.net/bkerndev/Docs/irqs.htm
 * Reference to 8259: http://wiki.osdev.org/PIC
 *                    http://bochs.sourceforge.net/techspec/intel-8259a-pic.pdf.gz
 */
void irq_remap()
{
    outp(0x20, 0x11);
    outp(0xA0, 0x11);
    outp(0x21, 0x20);
    outp(0xA1, 0x28);
    outp(0x21, 0x04);
    outp(0xA1, 0x02);
    outp(0x21, 0x01);
    outp(0xA1, 0x01);
    outp(0x21, 0x0);
    outp(0xA1, 0x0);
}

void int0()
{

	println("Interrupt 0");
	__asm__("xchg %bx,%bx");
	__asm__("movl $0xdeadbeef, %eax\n");
}

void int1()
{
	println("Interrupt 1");
	__asm__("pop %ebp"); // function call does a push
	
}

void int2()
{
	println("Interrupt 2");
	__asm__("pop %ebp"); // function call does a push
	
}

void int3()
{
	println("Interrupt 3");
	__asm__("pop %ebp"); // function call does a push
	
}

void int4()
{
	println("Interrupt 4");
	__asm__("pop %ebp"); // function call does a push
	
}

void int5()
{
	println("Interrupt 5");
	__asm__("pop %ebp"); // function call does a push
	
}

void int6()
{
	println("Interrupt 6");
	
}

void int7()
{
	println("Interrupt 7");
	
}

void int8()
{
	println("Interrupt 8");
	__asm__("pop %eax"); // error code
	
}

void int9()
{
	println("Interrupt 9");
	
}

void int10()
{
	println("Interrupt 10");
	__asm__("pop %ebp"); // function call does a push
	__asm__("pop %eax"); // error code
	
}

void int11()
{
	println("Interrupt 11");
	__asm__("pop %eax"); // error code
	
}

void int12()
{
	println("Interrupt 12");
	__asm__("pop %eax"); // error code
	
}

void int13()
{
	println("Interrupt 13");
	__asm__("pop %eax"); // error code
}

void int14()
{
	println("Interrupt 14");
	__asm__("pop %eax"); // error code
	
}

void int15()
{
	println("Interrupt 15");
	
}

void int16()
{
	println("Interrupt 16");
	
}

void int17()
{
	println("Interrupt 17");
	
}

void int18()
{
	println("Interrupt 18");
	
}

void int19()
{
	println("Interrupt 19");
	
}

void int20()
{
	println("Interrupt 20");
	
}

void int21()
{
	println("Interrupt 21");
	
}

void int22()
{
	println("Interrupt 22");
	
}

void int23()
{
	println("Interrupt 23");
	
}

void int24()
{
	println("Interrupt 24");
	
}

void int25()
{
	println("Interrupt 25");
	
}

void int26()
{
	println("Interrupt 26");
	
}

void int27()
{
	println("Interrupt 27");
	
}

void int28()
{
	println("Interrupt 28");
	
}

void int29()
{
	println("Interrupt 29");
	
}

void int30()
{
	println("Interrupt 30");
	
}

void int31()
{
	println("Interrupt 31");
	
}

void int32()
{
	//println("Interrupt 32");
	//__asm__("movl $0xdeadface, %eax");
	
}

void int33()
{
	println("Interrupt 33");
	
}

void int34()
{
	println("Interrupt 34");
	
}

void int35()
{
	println("Interrupt 35");
	
}

void int36()
{
	println("Interrupt 36");
	
}

void int37()
{
	println("Interrupt 37");
	
}

void int38()
{
	println("Interrupt 38");
	
}

void int39()
{
	println("Interrupt 39");
	
}

void int40()
{
	println("Interrupt 40");
	
}

void int41()
{
	println("Interrupt 41");
	
}

void int42()
{
	println("Interrupt 42");
	
}

void int43()
{
	println("Interrupt 43");
	
}

void int44()
{
	println("Interrupt 44");
	
}

void int45()
{
	println("Interrupt 45");
	
}

void int46()
{
	println("Interrupt 46");
	
}

void int47()
{
	println("Interrupt 47");
	
}

void int48()
{
	println("Interrupt 48");
	
}

void int49()
{
	println("Interrupt 49");
}

void int50()
{
	println("Interrupt 50");
}

void int51()
{
	println("Interrupt 51");
}

void int52()
{
	println("Interrupt 52");
}

void int53()
{
	println("Interrupt 53");
}

void int54()
{
	println("Interrupt 54");
}

void int55()
{
	println("Interrupt 55");
}

void int56()
{
	println("Interrupt 56");
}

void int57()
{
	println("Interrupt 57");
}

void int58()
{
	println("Interrupt 58");
}

void int59()
{
	println("Interrupt 59");
}

void int60()
{
	println("Interrupt 60");
}

void int61()
{
	println("Interrupt 61");
}

void int62()
{
	println("Interrupt 62");
}

void int63()
{
	println("Interrupt 63");
}

void int64()
{
	println("Interrupt 64");
}

void int65()
{
	println("Interrupt 65");
}

void int66()
{
	println("Interrupt 66");
}

void int67()
{
	println("Interrupt 67");
}

void int68()
{
	println("Interrupt 68");
}

void int69()
{
	println("Interrupt 69");
}

void int70()
{
	println("Interrupt 70");
}

void int71()
{
	println("Interrupt 71");
}

void int72()
{
	println("Interrupt 72");
}

void int73()
{
	println("Interrupt 73");
}

void int74()
{
	println("Interrupt 74");
}

void int75()
{
	println("Interrupt 75");
}

void int76()
{
	println("Interrupt 76");
}

void int77()
{
	println("Interrupt 77");
}

void int78()
{
	println("Interrupt 78");
}

void int79()
{
	println("Interrupt 79");
}

void int80()
{
	println("Interrupt 80");
}

void int81()
{
	println("Interrupt 81");
}

void int82()
{
	println("Interrupt 82");
}

void int83()
{
	println("Interrupt 83");
}

void int84()
{
	println("Interrupt 84");
}

void int85()
{
	println("Interrupt 85");
}

void int86()
{
	println("Interrupt 86");
}

void int87()
{
	println("Interrupt 87");
}

void int88()
{
	println("Interrupt 88");
}

void int89()
{
	println("Interrupt 89");
}

void int90()
{
	println("Interrupt 90");
}

void int91()
{
	println("Interrupt 91");
}

void int92()
{
	println("Interrupt 92");
}

void int93()
{
	println("Interrupt 93");
}

void int94()
{
	println("Interrupt 94");
}

void int95()
{
	println("Interrupt 95");
}

void int96()
{
	println("Interrupt 96");
}

void int97()
{
	println("Interrupt 97");
}

void int98()
{
	println("Interrupt 98");
}

void int99()
{
	println("Interrupt 99");
}

void int100()
{
	println("Interrupt 100");
}

void int101()
{
	println("Interrupt 101");
}

void int102()
{
	println("Interrupt 102");
}

void int103()
{
	println("Interrupt 103");
}

void int104()
{
	println("Interrupt 104");
}

void int105()
{
	println("Interrupt 105");
}

void int106()
{
	println("Interrupt 106");
}

void int107()
{
	println("Interrupt 107");
}

void int108()
{
	println("Interrupt 108");
}

void int109()
{
	println("Interrupt 109");
}

void int110()
{
	println("Interrupt 110");
}

void int111()
{
	println("Interrupt 111");
}

void int112()
{
	println("Interrupt 112");
}

void int113()
{
	println("Interrupt 113");
}

void int114()
{
	println("Interrupt 114");
}

void int115()
{
	println("Interrupt 115");
}

void int116()
{
	println("Interrupt 116");
}

void int117()
{
	println("Interrupt 117");
}

void int118()
{
	println("Interrupt 118");
}

void int119()
{
	println("Interrupt 119");
}

void int120()
{
	println("Interrupt 120");
}

void int121()
{
	println("Interrupt 121");
}

void int122()
{
	println("Interrupt 122");
}

void int123()
{
	println("Interrupt 123");
}

void int124()
{
	println("Interrupt 124");
}

void int125()
{
	println("Interrupt 125");
}

void int126()
{
	println("Interrupt 126");
}

void int127()
{
	println("Interrupt 127");
}

void int128()
{
	println("Interrupt 128");
}

void int129()
{
	println("Interrupt 129");
}

void int130()
{
	println("Interrupt 130");
}

void int131()
{
	println("Interrupt 131");
}

void int132()
{
	println("Interrupt 132");
}

void int133()
{
	println("Interrupt 133");
}

void int134()
{
	println("Interrupt 134");
}

void int135()
{
	println("Interrupt 135");
}

void int136()
{
	println("Interrupt 136");
}

void int137()
{
	println("Interrupt 137");
}

void int138()
{
	println("Interrupt 138");
}

void int139()
{
	println("Interrupt 139");
}

void int140()
{
	println("Interrupt 140");
}

void int141()
{
	println("Interrupt 141");
}

void int142()
{
	println("Interrupt 142");
}

void int143()
{
	println("Interrupt 143");
}

void int144()
{
	println("Interrupt 144");
}

void int145()
{
	println("Interrupt 145");
}

void int146()
{
	println("Interrupt 146");
}

void int147()
{
	println("Interrupt 147");
}

void int148()
{
	println("Interrupt 148");
}

void int149()
{
	println("Interrupt 149");
}

void int150()
{
	println("Interrupt 150");
}

void int151()
{
	println("Interrupt 151");
}

void int152()
{
	println("Interrupt 152");
}

void int153()
{
	println("Interrupt 153");
}

void int154()
{
	println("Interrupt 154");
}

void int155()
{
	println("Interrupt 155");
}

void int156()
{
	println("Interrupt 156");
}

void int157()
{
	println("Interrupt 157");
}

void int158()
{
	println("Interrupt 158");
}

void int159()
{
	println("Interrupt 159");
}

void int160()
{
	println("Interrupt 160");
}

void int161()
{
	println("Interrupt 161");
}

void int162()
{
	println("Interrupt 162");
}

void int163()
{
	println("Interrupt 163");
}

void int164()
{
	println("Interrupt 164");
}

void int165()
{
	println("Interrupt 165");
}

void int166()
{
	println("Interrupt 166");
}

void int167()
{
	println("Interrupt 167");
}

void int168()
{
	println("Interrupt 168");
}

void int169()
{
	println("Interrupt 169");
}

void int170()
{
	println("Interrupt 170");
}

void int171()
{
	println("Interrupt 171");
}

void int172()
{
	println("Interrupt 172");
}

void int173()
{
	println("Interrupt 173");
}

void int174()
{
	println("Interrupt 174");
}

void int175()
{
	println("Interrupt 175");
}

void int176()
{
	println("Interrupt 176");
}

void int177()
{
	println("Interrupt 177");
}

void int178()
{
	println("Interrupt 178");
}

void int179()
{
	println("Interrupt 179");
}

void int180()
{
	println("Interrupt 180");
}

void int181()
{
	println("Interrupt 181");
}

void int182()
{
	println("Interrupt 182");
}

void int183()
{
	println("Interrupt 183");
}

void int184()
{
	println("Interrupt 184");
}

void int185()
{
	println("Interrupt 185");
}

void int186()
{
	println("Interrupt 186");
}

void int187()
{
	println("Interrupt 187");
}

void int188()
{
	println("Interrupt 188");
}

void int189()
{
	println("Interrupt 189");
}

void int190()
{
	println("Interrupt 190");
}

void int191()
{
	println("Interrupt 191");
}

void int192()
{
	println("Interrupt 192");
}

void int193()
{
	println("Interrupt 193");
}

void int194()
{
	println("Interrupt 194");
}

void int195()
{
	println("Interrupt 195");
}

void int196()
{
	println("Interrupt 196");
}

void int197()
{
	println("Interrupt 197");
}

void int198()
{
	println("Interrupt 198");
}

void int199()
{
	println("Interrupt 199");
}

void int200()
{
	println("Interrupt 200");
}

void int201()
{
	println("Interrupt 201");
}

void int202()
{
	println("Interrupt 202");
}

void int203()
{
	println("Interrupt 203");
}

void int204()
{
	println("Interrupt 204");
}

void int205()
{
	println("Interrupt 205");
}

void int206()
{
	println("Interrupt 206");
}

void int207()
{
	println("Interrupt 207");
}

void int208()
{
	println("Interrupt 208");
}

void int209()
{
	println("Interrupt 209");
}

void int210()
{
	println("Interrupt 210");
}

void int211()
{
	println("Interrupt 211");
}

void int212()
{
	println("Interrupt 212");
}

void int213()
{
	println("Interrupt 213");
}

void int214()
{
	println("Interrupt 214");
}

void int215()
{
	println("Interrupt 215");
}

void int216()
{
	println("Interrupt 216");
}

void int217()
{
	println("Interrupt 217");
}

void int218()
{
	println("Interrupt 218");
}

void int219()
{
	println("Interrupt 219");
}

void int220()
{
	println("Interrupt 220");
}

void int221()
{
	println("Interrupt 221");
}

void int222()
{
	println("Interrupt 222");
}

void int223()
{
	println("Interrupt 223");
}

void int224()
{
	println("Interrupt 224");
}

void int225()
{
	println("Interrupt 225");
}

void int226()
{
	println("Interrupt 226");
}

void int227()
{
	println("Interrupt 227");
}

void int228()
{
	println("Interrupt 228");
}

void int229()
{
	println("Interrupt 229");
}

void int230()
{
	println("Interrupt 230");
}

void int231()
{
	println("Interrupt 231");
}

void int232()
{
	println("Interrupt 232");
}

void int233()
{
	println("Interrupt 233");
}

void int234()
{
	println("Interrupt 234");
}

void int235()
{
	println("Interrupt 235");
}

void int236()
{
	println("Interrupt 236");
}

void int237()
{
	println("Interrupt 237");
}

void int238()
{
	println("Interrupt 238");
}

void int239()
{
	println("Interrupt 239");
}

void int240()
{
	println("Interrupt 240");
}

void int241()
{
	println("Interrupt 241");
}

void int242()
{
	println("Interrupt 242");
}

void int243()
{
	println("Interrupt 243");
}

void int244()
{
	println("Interrupt 244");
}

void int245()
{
	println("Interrupt 245");
}

void int246()
{
	println("Interrupt 246");
}

void int247()
{
	println("Interrupt 247");
}

void int248()
{
	println("Interrupt 248");
}

void int249()
{
	println("Interrupt 249");
}

void int250()
{
	println("Interrupt 250");
}

void int251()
{
	println("Interrupt 251");
}

void int252()
{
	println("Interrupt 252");
}

void int253()
{
	println("Interrupt 253");
}

void int254()
{
	println("Interrupt 254");
}

void int255()
{
	println("Interrupt 255");
}

